#include <iostream>
#include <string>
#include <fstream>
#include "viml/vm.h"
#include "viml/compiler.h"
#include "viml/parser.h"
#include "viml/ast_printer.h"
#include "viml/ast_detailed_printer.h"
#include "viml/ast_json_printer.h"

void print_usage(const char* program_name) {
    std::cout << "Usage: " << program_name << " [options] <script.vim>\n";
    std::cout << "Options:\n";
    std::cout << "  -h, --help      显示帮助信息\n";
    std::cout << "  -v, --version   显示版本信息\n";
    std::cout << "  -d, --debug     启用调试模式\n";
    std::cout << "  --ast           导出JSON格式的抽象语法树，便于程序解析\n";
    std::cout << "  --ast-pretty    导出格式化的抽象语法树(AST)\n";
    std::cout << "  --ast-simple    导出简单的抽象语法树(AST)\n";
    std::cout << "  --ast-analysis  导出详细的AST分析报告，包含语义信息\n";
}

void print_version() {
    std::cout << "VimL Compiler and Virtual Machine v0.1.0\n";
    std::cout << "Built with C++17\n";
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        print_usage(argv[0]);
        return 1;
    }

    std::string filename;
    bool debug_mode = false;
    bool export_ast = false;
    bool export_ast_pretty = false;
    bool export_ast_simple = false;
    bool export_ast_analysis = false;

    // 解析命令行参数
    for (int i = 1; i < argc; ++i) {
        std::string arg = argv[i];
        if (arg == "-h" || arg == "--help") {
            print_usage(argv[0]);
            return 0;
        } else if (arg == "-v" || arg == "--version") {
            print_version();
            return 0;
        } else if (arg == "-d" || arg == "--debug") {
            debug_mode = true;
        } else if (arg == "--ast") {
            export_ast = true;
        } else if (arg == "--ast-pretty") {
            export_ast_pretty = true;
        } else if (arg == "--ast-simple") {
            export_ast_simple = true;
        } else if (arg == "--ast-analysis") {
            export_ast_analysis = true;
        } else if (arg[0] != '-') {
            filename = arg;
        } else {
            std::cerr << "未知选项: " << arg << std::endl;
            print_usage(argv[0]);
            return 1;
        }
    }

    if (filename.empty()) {
        std::cerr << "错误: 请指定VimL脚本文件" << std::endl;
        print_usage(argv[0]);
        return 1;
    }

    try {
        // 读取源文件
        std::ifstream file(filename);
        if (!file.is_open()) {
            std::cerr << "错误: 无法打开文件 " << filename << std::endl;
            return 1;
        }

        std::string source((std::istreambuf_iterator<char>(file)),
                          std::istreambuf_iterator<char>());
        file.close();

        // 创建编译器和虚拟机
        viml::Compiler compiler;
        viml::VM vm;

        if (debug_mode) {
            std::cout << "调试模式已启用" << std::endl;
            vm.set_debug_mode(true);
        }

        // 如果要求导出AST，则解析并输出AST
        if (export_ast || export_ast_pretty || export_ast_simple || export_ast_analysis) {
            std::cout << "解析中..." << std::endl;
            viml::Parser parser(source);
            auto program = parser.parse();
            
            std::cout << "\n======= 抽象语法树 (AST) =======" << std::endl;
            
            if (export_ast) {
                // 使用Visitor模式的JSON输出器
                viml::ASTJsonPrinter json_printer;
                program->accept(json_printer);
                std::cout << json_printer.get_json() << std::endl;
            } else if (export_ast_pretty) {
                // 现有的格式化输出
                viml::ASTPrettyPrinter printer;
                program->accept(printer);
                std::cout << printer.get_output() << std::endl;
            } else if (export_ast_simple) {
                // 简单输出
                std::cout << program->to_string() << std::endl;
            } else if (export_ast_analysis) {
                // 详细分析报告
                viml::DetailedOutputConfig config;
                config.detail_level = viml::DetailedOutputConfig::DetailLevel::FULL;
                viml::ASTDetailedPrinter analysis_printer(config);
                analysis_printer.set_source_code(source);
                program->accept(analysis_printer);
                std::cout << analysis_printer.get_detailed_output() << std::endl;
            }
            
            std::cout << "==============================" << std::endl;
            return 0;
        }

        // 第二阶段优化：启用记忆化机制
        vm.set_memoization_enabled(true);
        vm.optimize_memoization_for_recursive_algorithms();
        
        // 自动函数纯度分析：解析源代码并自动添加纯函数到记忆化白名单
        if (!export_ast && !export_ast_pretty) {
            viml::Parser parser_for_analysis(source);
            auto program_for_analysis = parser_for_analysis.parse();
            
            if (debug_mode) {
                std::cout << "正在进行自动函数纯度分析..." << std::endl;
            }
            
            for (auto& stmt : program_for_analysis->statements) {
                if (auto func_stmt = dynamic_cast<viml::FunctionStatement*>(stmt.get())) {
                    auto result = vm.analyze_and_add_function(*func_stmt);
                    if (debug_mode) {
                        if (result.is_pure) {
                            std::cout << "  ✓ " << func_stmt->name << " 已添加到记忆化白名单" << std::endl;
                        } else {
                            std::cout << "  ✗ " << func_stmt->name << " 未添加到记忆化白名单: " << result.reason << std::endl;
                        }
                    }
                }
            }
        }
        
        // 编译源代码
        std::cout << "编译 " << filename << "..." << std::endl;
        auto bytecode = compiler.compile(source, filename);
        
        // 显示字节码（调试）
        if (debug_mode) {
            std::cout << "生成的字节码:" << std::endl;
            bytecode->dump();
        }

        // 执行字节码
        std::cout << "执行中..." << std::endl;
        auto result = vm.execute(bytecode);

        std::cout << "执行完成" << std::endl;
        
        // 调试模式下显示记忆化统计信息
        if (debug_mode && vm.is_memoization_enabled()) {
            auto stats = vm.get_memoization_statistics();
            if (stats.hits > 0 || stats.misses > 0) {
                std::cout << "记忆化统计:" << std::endl;
                std::cout << "  缓存命中: " << stats.hits << " 次" << std::endl;
                std::cout << "  缓存未命中: " << stats.misses << " 次" << std::endl;
                std::cout << "  命中率: " << stats.hit_rate << "%" << std::endl;
            }
        }
        return 0;

    } catch (const std::exception& e) {
        std::cerr << "错误: " << e.what() << std::endl;
        return 1;
    }
}